AWS IoT Greengrass で Windows 環境に bat ファイルのコンポーネントをカスタムビルドしてデプロイする
はじめに
AWS IoT Greengrass は、エッジデバイス上のアプリケーションの開発・管理を効率的に行う事ができるサービスです。
サポートするエッジデバイスの OS は、Linux の他に Windows もサポートしています。
- アーキテクチャ:
- 64ビット
- バージョン:
- Windows 10
- Windows 11
- Windows Server 2019
- Windows Server 2022
これまで Linux 環境でしか Greengrass を触ったことなかったのですが、今回 Windows 環境で使うことがあったので紹介したいと思います。
構築内容
AWS にも公式ブログがあり、基本的な内容はこの記事に沿って進めますが、少し古い記事なのでいくつか作業内容を変えてやってみたいと思います。
上記ブログとは異なる点は下記になります。
- Greengrass インストール用の IAM 認証情報の利用方法を、IAM User ではなく IAM Role に変更
- カスタムコンポーネントの作成をすべて手動ではなく、GDK CLI を利用する形に変更
ポイント
特に、本記事で工夫したのは bat ファイルで作ったコンポーネントを GDK の「カスタムビルド」を用いて開発した点です。
これまで、Linux 環境では Python を使ってコンポーネントを作ることが多かったのですが、Python などインタープリタ系の言語を使う場合、コンポーネントのビルドには zip
を使います。
Linux 環境であれば zip
コマンドが標準的にシステムにインストールされていることが多いので、特に問題なくアーティファクトを解凍してコンポーネントをデプロイできます。
しかし、Windows 環境の場合は相当するコマンドが標準的に用意されていないので、何かしらのアーカイバをインストールして環境変数の PATH に通す必要があります。もしくは PowerShell
の解凍コマンドを使うことになるかと思います。
個人的には、あまり Windows 環境に手を加えたくなく、また PowerShellに不慣れだったので、bat ファイルをそのままビルドして、bat ファイルのまま Windows マシンにデプロイしたいと考えました。
このように標準で用意されている方式以外の方法でビルドするために、GDK では「カスタムビルド」という機能があり、ユーザーの任意の方法でビルドできます。
具体的な使い方について、これよりご紹介していきたいと思います。
開発環境
用意するのは次の2点です。
- GDK CLI が利用できる環境:開発環境
- Windows PC:コンポーネントが動くエッジデバイス環境
GDK CLI の環境はどこでも構いません。コンポーネントを動かす Windows PC 上でも構いませんし、AWS CloudShell でも問題ありません。私はすでに普段使っている MacBook にインストール済みなので、Mac 上で開発を行います。
Windows PC は手元にあった Windows 11 Pro のマシンを使います。
物理的に Windows 環境がなければ、EC2 で Windows インスタンスを利用してもいいかと思います。
実際に利用した開発環境の全体図は次のとおりです。
それでは、具体的な作業を進めていきましょう。
全体の流れ
- Windows 環境に Java をインストールする
- AWS IoT Greengrass を実行する Windows 環境にローカルユーザーを作成する
- AWS Command Line Interface(CLI)のバージョン 2 を Windows にインストールする
- Greengrass インストール用の IAM クレデンシャルを取得する環境を作る
- AWS IoT Greengrassのインストーラーをダウンロードして実行する
- GDK CLI を開発環境にインストールする
- AWS IoT Greengrass コンポーネントを作成しデプロイする
- コンポーネントの動作確認をする
Windows 環境に Java 実行環境をインストール
Greengrass (V2) では Java が必要になります。(最低でも Java バージョン 8 が必要)
私の環境ではインストールされていなかったのでインストールしておきます。該当の Windows は 64bit だったので、Java も 64bit 版を選択しました。
インストーラを実行するだけなので、手順の記載は省略させていただきます。
コマンドプロンプトで java -version
と入力して確認できます。
AWS IoT Greengrass を実行する Windows マシンに、ローカルユーザーを作成
Greengrass を利用するためには、対象の環境に専用のユーザー(ggc_user
)を作成する必要があります。
そのために Windows 環境に「MicrosoftのPsExecユーティリティ」をインストールします。
インストールされていない場合は、下記からユーティリティをダウンロードしてください。ZIP ファイルを解凍すると psexec.exe
というファイルがあるので、C:\Windows\System32
にコピペします。
コピペできたら、コマンドプロンプトを「管理者として実行」を選択して起動し、 以下のコマンドを実行します。パスワードは任意のものを指定してください。
net user /add ggc_user <password>
続けて次のコマンドを実行します。<password>
は、先ほど使用したパスワードに置き換えてください。
cd C:\Windows\System32
psexec -s cmd /c cmdkey /generic:ggc_user /user:ggc_user /pass:<password>
Windows PC に AWS CLI(V2)をインストール
次に、対象の Windows 環境に AWS CLI(V2)をインストールします。
msiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msi
AWS CLI のインストールも確認できました。
Greengrass インストール用の IAM クレデンシャルの用意と設定
Greengrass ソフトウェアのインストール時に、AWS IoT にデバイス情報の登録や IAM 設定などを行うため、Windows マシンに IAM 権限を付与する必要があります。
AWS のブログでは、IAM User を発行して、そのシークレットキーを Windows 上に静的に設置しています。
インストール完了後にこれらの情報を Windows 上から削除すれば問題ありませんが、削除漏れや気づかぬうちに漏洩してしまう危険性もあるので、今回は IAM Role を使うことにします。
(AWS の記事では IAMFullAccess
の権限を付与しているので、取り扱いには注意する必要があります。)
インストールに必要なIAM Role の作成
下記のポリシーを持つ IAM Role を作ります。名前は何でも構いません。今回は greengrass-v2-provision-role
という名前にしました。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CreateTokenExchangeRole",
"Effect": "Allow",
"Action": [
"iam:AttachRolePolicy",
"iam:CreatePolicy",
"iam:CreateRole",
"iam:GetPolicy",
"iam:GetRole",
"iam:PassRole"
],
"Resource": "*"
},
{
"Sid": "CreateIoTResources",
"Effect": "Allow",
"Action": [
"iot:AddThingToThingGroup",
"iot:AttachPolicy",
"iot:AttachThingPrincipal",
"iot:CreateKeysAndCertificate",
"iot:CreatePolicy",
"iot:CreateRoleAlias",
"iot:CreateThing",
"iot:CreateThingGroup",
"iot:DescribeEndpoint",
"iot:DescribeRoleAlias",
"iot:DescribeThingGroup",
"iot:GetPolicy"
],
"Resource": "*"
},
{
"Sid": "DeployDevTools",
"Effect": "Allow",
"Action": [
"greengrass:CreateDeployment",
"iot:CancelJob",
"iot:CreateJob",
"iot:DeleteThingShadow",
"iot:DescribeJob",
"iot:DescribeThing",
"iot:DescribeThingGroup",
"iot:GetThingShadow",
"iot:UpdateJob",
"iot:UpdateThingShadow"
],
"Resource": "*"
}
]
}
参考ドキュメントでは Resource
の指定がありますが、今回は分かりやすさを優先するため *
を指定しています。
また信頼関係も別途セットします。信頼関係の内容は AWS 上の作業者の種類で変わります。
IAM Role
でスイッチロールして実施している場合- IAM User でログインして実施している場合
IAM User で作業している場合
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<YOUR_AWS_ACCOUNT_ID>:user/<YOUR_IAM_USER_NAME>"
},
"Action": "sts:AssumeRole"
}
]
}
IAM Role
でスイッチロールしている場合
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<YOUR_AWS_ACCOUNT_ID>:role/<YOUR_IAM_ROLE_NAME>"
},
"Action": "sts:AssumeRole"
}
]
}
一時クレデンシャルの取得
次に、インストール時に必要な IAM の一時クレデンシャルを取得します。
一時クレデンシャルの取得は、AWS CloudShell で実行します。get-caller-identity
というコマンドで得られるアクセスキーなどを Windows 上の環境変数にセットするのですが、作業ミスを防止するため下記のコマンド内容をコピペで実行します。
--role-arn
に指定する IAM Roleの名前は先程作成した名前(greengrass-v2-provision-role
)を指定してください。
OUTPUT=`aws sts assume-role \
--role-arn arn:aws:iam::<YOUR_AWS_ACCOUNT_ID>:role/greengrass-v2-provision-role \
--role-session-name "RoleSession01"
`
echo "############ Copy and Paste the following credential to Greengrass Core Divice! ############" ; \
echo "set AWS_ACCESS_KEY_ID=`echo $OUTPUT | jq -r .Credentials.AccessKeyId`" ; \
echo "set AWS_SECRET_ACCESS_KEY=`echo $OUTPUT | jq -r .Credentials.SecretAccessKey`" ; \
echo "set AWS_SESSION_TOKEN=`echo $OUTPUT | jq -r .Credentials.SessionToken`" ; \
echo ""
実行すると赤枠のような出力が返ってくるので、この内容をコピーします。
対象の Windows マシンでコマンドプロンプトを「管理者として実行」で開いて、先程の内容をコピペします。
これで Greenrass をインストールする際に必要な AWS 側の権限情報を Windows マシンにセットできました。
この認証が有効な時間はデフォルトで 1 時間なので、Greengrass のインストールは 1 時間以内に行います。1 時間以上経過してしまった場合は、再度先ほどのコマンドを実行して環境変数をセットし直してください。
環境変数をセットしたコマンドプロントは開いたままにしておきます。 このウィンドウでインストーラを後ほど実行します。
Windows マシンに Greengrass をインストール
ようやく Greengrass インストールの準備ができました。ここからは AWS のマネジメントコンソールに表示される手順 に沿って作業を行います。
Greengrass のコンソール画面より 「1つの Core デバイスをセットアップ」 をクリックします。
ステップ 1 では、適当なコアデバイス名をセットします。
ステップ 2 では、デプロイグループは新たに作成します。(既存のものなどを使いたい場合は、適宜変更してください。)
ステップ 3 は、すでに実行済みの作業があるので必要な作業のみ行います。
- インストールするランタイム: 「Nucleus Classic」 を選択
- Nucleus Lite は 2024年12月にリリースされたもので Windows は未サポートです
- OS の種別: 「Windows」 を選択
次に画面下側にスクロールするとインストーラのダウンロードに関する説明があります。
ここで「.zip をダウンロード」と書かれている 上側のコマンド内容をコピー します。
Windows マシンのコマンドプロンプトを開いて(一般ユーザーでOKです)、コピーしたコマンドをコピペで実行します。
コマンドを実行すると、実行したフォルダーに greengrass-nucleus-latest.zip
というファイルがあるはずです。
ダウンロードしたインストーラーを実行するコマンドも先程の AWS コンソール画面に掲載されていますが、今回はこれを使いません。
(使っても構いません)
インストールを実行するために、コマンドプロンプトを「管理者として実行」で開きます。
(先ほど環境変数をセットしたコマンドプロントのウィンドウをそのまま使います)
次に、インストーラをダウンロードしたフォルダに移動します。私の作業では一般ユーザーの「ホーム」にダウンロードしたので次のようになります。環境に合わせて実行してください。
C:\Windows\System32>cd \Users\<MY_USER_NAME>
肝心のインストールコマンドの内容ですが、今回は AWS ドキュメントにあるサンプルを参考にしたものを実行します。具体的には次のようになります。
java -Droot="C:\greengrass\v2" "-Dlog.store=FILE" ^
-jar ./GreengrassInstaller/lib/Greengrass.jar ^
--aws-region ap-northeast-1 ^
--thing-name WindowsTest01 ^
--thing-group-name WindowsTestGroup ^
--thing-policy-name WindowsTestGreengrassV2IoTThingPolicy ^
--tes-role-name WindowsTestGreengrassV2TokenExchangeRole ^
--tes-role-alias-name WindowsTestGreengrassCoreTokenExchangeRoleAlias ^
--component-default-user ggc_user ^
--provision true ^
--setup-system-service true
コンソールに表示されていたコマンドとの違いは、--tes-role-name
と --tes-role-alias-name
オプションの有無です。このオプションがなければ TES Role が自動的に作成されます。
個人的には、どのデバイスにどの TES Role が紐づいているかを分かりやすく区別したいのでオプションで指定するようにしています。
コンソールに表示されるコマンドは、指定した「コアデバイス名」や「グループ名」にもとづいてコマンドを生成してくれます。そのため上記のコマンドを作るには、コンソールに表示されていたコマンドをコピペして、--tes-role-name
と --tes-role-alias-name
を追加すれば OK です。
なお、この TES Role(トークン交換サービス ロール)は、デプロイしたコンポーネントが AWS 側の各種サービスにアクセスする際に利用される IAM Role です。例えば、コンポーネントが Secrets Manager を利用する場合は、このロールに Secrets Manager の権限を付与します。
インストールが成功すると Successfully...
というメッセージが表示されます。以下はインストールが成功した際の出力です。
無事に Greengrass がインストールできていれば、AWS 側のコンソールにも 「Greengrass コアデバイス」 として表示されるようになります。
GDK CLI のインストール
Greengrass のインストールが終われば、次はコンポーネントの作成になります。
冒頭で参考に挙げた記事ではコンポーネントの開発はすべて手動で行われています。お試しの場合はこれでもいいのですが、本格的に利用する場合は、コンポーネントを継続的に更新したり、作成したアプリをビルドして Greengrass に登録したりといった作業が発生します。これを毎回手動で行うのは辛い作業になります。
現在は、公式ドキュメントでも GDK CLI(Greengrass Development Kit CLI)というツールを使うことが標準となっているので、今回も GDK を使います。
GDK は、開発を行う環境にインストールするものなので、エッジ環境で動くデバイスとは別のマシン環境にインストールして使っても問題ありません。ただし、開発環境とエッジデバイスの環境が異なる場合(CPU アーキテクチャなど)は、利用する言語次第でコンポーネントのビルド時にクロスコンパイルする必要が出るなど、注意が必要になります。
今回は Mac 上にインストールした GDK で作業しますが、作成するコンポーネントは単一の bat ファイルなので、このような注意は必要ないかと思います。
GDK CLI のインストールは、下記ドキュメントを参照してください。
カスタムコンポーネントの作成
最初にテンプレートを指定して、開発環境を初期化します。
gdk component init \
--language python \
--name windows-test-20250106 \
--template HelloWorld
初期化時に指定できる言語は、Python か Java の 2 つになります。インタープリタ系の言語なら Python
の指定でいいと思います。
--name
で指定したディレクトリに必要なファイルがダウンロードされるので、作業ディレクトリに移動して開発を行っていきます。
cd windows-test-20250106
このディレクトリは次のようなフォルダ構成になります。
.
├── README.md
├── gdk-config.json
├── main.py
├── recipe.yaml
├── src
│ └── greeter.py
└── tests
└── test_greeter.py
recipe.yaml の編集
最初にレシピを編集します。今回は bat ファイルをそのままコンポーネントとして登録(zipなどで圧縮せず)して、デプロイ時も bat ファイルのまま実行したかったので、Artifacts
の記載もそのようにしています。
ComponentName
は適当に変えてください。
本来なら ComponentName
も変数として参照できるはずなのですが、ここは明示的にコンポーネント名を指定しないと、コンポーネントを Greengrass に登録する時(gdk component publish
実行時)にエラーになってしまいました。
---
RecipeFormatVersion: "2020-01-25"
ComponentName: "com.example.windowstest01"
ComponentVersion: "{COMPONENT_VERSION}"
ComponentDescription: "This is sample component for Windows."
ComponentPublisher: "{COMPONENT_AUTHOR}"
ComponentConfiguration:
DefaultConfiguration:
Message: "World"
Manifests:
- Platform:
os: windows
Artifacts:
- Uri: "s3://BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION/windowstest01.bat"
Unarchive: NONE
Lifecycle:
run: "{artifacts:path}/windowstest01.bat"
gdk-config.json の編集
gdk-config.json
を次のように編集します。ポイントは 7 〜 13 行目のカスタムビルドの指定です。
bat ファイルをそのままコンポーネントとして登録したいので、カスタムビルドの内容をシェルスクリプト(build-custom.sh
)にまとめています。
bucket
の指定は、ビルドしたアーティファクトが保存される S3 バケットの指定です。ここで指定した文字列が含まれる形で バケットが作成されます。
{
"component": {
"com.example.windowstest01": {
"author": "CM-ICHIDA",
"version": "NEXT_PATCH",
"build": {
"build_system": "custom",
"custom_build_command": [
"bash",
"build-custom.sh",
"com.example.windowstest01",
"NEXT_PATCH"
]
},
"publish": {
"bucket": "greengrass-windows-test-20250106",
"region": "ap-northeast-1"
}
}
},
"gdk_version": "1.6.1"
}
次に、カスタムビルドで指定している build-custom.sh
を次の内容で作成します。
修正済みのレシピをビルドディレクトリにコピーして、カレントディレクトリにある bat ファイルすべてをビルドディレクトリにコピーしています。
if [ $# -ne 2 ]; then
echo 1>&2 "Usage: $0 COMPONENT-NAME COMPONENT-VERSION"
exit 3
fi
COMPONENT_NAME=$1
VERSION=$2
# copy recipe to greengrass-build
cp recipe.yaml ./greengrass-build/recipes
# copy archive to greengrass-build (build component)
cp ./*.bat ./greengrass-build/artifacts/$COMPONENT_NAME/$VERSION/
標準のビルド方式でサポートされている方法を使う場合は、これらの処理は自動で行われますが、カスタムビルドでは自分で処理を行う必要があるため、このような処理を記載しています。
公式ドキュメントにもそのような記載があります。
今回は、Mac で開発しているためビルド用にシェルスクリプトを作りましたが、Windows など他のプラットフォームで開発する場合は、その環境に応じた形に修正してください。
windowstest01.bat の作成
コンポーネント本体のアプリを作成します。今回は AWS ブログにあった内容をそのまま流用させていただきます。記事では chcp
の部分が全角になっていたのでコピペする際は注意してください。(本記事では修正済みです)
@ECHO OFF
chcp 437
>hardware.txt (
:: This batch file will discover the windows version we are using and store to a text file
TITLE My System Info
ECHO ==========================
ECHO WINDOWS INFO
ECHO ============================
systeminfo | findstr /c:"OS Name"
systeminfo | findstr /c:"OS Version"
systeminfo | findstr /c:"System Type"
)
このコンポーネントが実行されると、コンポーネントの実行フォルダ(C:\greengrass\v2\work\com.example.windowstest01
)に Windows マシンの情報が書かれたファイル(hardware.txt
)が出力されるはずです。
コンポーネントのビルド & パブリッシュ
準備ができたらコンポーネントをビルドします。
$ gdk component build
[2025-01-06 17:11:54] INFO - New version of GDK CLI - 1.6.2 is available. Please update the cli using the command `pip3 install git+https://github.com/aws-greengrass/aws-greengrass-gdk-cli.git@v1.6.2`.
[2025-01-06 17:11:55] INFO - Discovered 1.2.0 as latest GTF release name.
[2025-01-06 17:11:55] INFO - Building the component 'com.example.windowstest01' with the given project configuration.
[2025-01-06 17:11:55] INFO - Using custom build configuration to build the component.
[2025-01-06 17:11:55] INFO - Running the following command
['bash', './build-custom.sh', 'com.example.windowstest01', 'NEXT_PATCH']
ビルドできたらコンポーネントを Greengrass に登録します。この処理ではビルドしてできたアーティファクトを S3 にアップロードするとともに、Greengrass コンポーネントに登録します。
$ gdk component publish
[2025-01-06 17:17:03] INFO - New version of GDK CLI - 1.6.2 is available. Please update the cli using the command `pip3 install git+https://github.com/aws-greengrass/aws-greengrass-gdk-cli.git@v1.6.2`.
[2025-01-06 17:17:03] INFO - Discovered 1.2.0 as latest GTF release name.
[2025-01-06 17:17:03] INFO - Found credentials in environment variables.
[2025-01-06 17:17:04] INFO - No private version of the component 'com.example.windowstest01' exist in the account. Using '1.0.0' as the next version to create.
[2025-01-06 17:17:04] INFO - Publishing the component 'com.example.windowstest01' with the given project configuration.
[2025-01-06 17:17:04] INFO - Uploading the component built artifacts to s3 bucket.
[2025-01-06 17:17:04] INFO - Uploading component artifacts to S3 bucket: greengrass-windows-test-20250106-ap-northeast-1-852697527974. If this is your first time using this bucket, add the 's3:GetObject' permission to each core device's token exchange role to allow it to download the component artifacts. For more information, see https://docs.aws.amazon.com/greengrass/v2/developerguide/device-service-role.html.
[2025-01-06 17:17:04] INFO - Not creating an artifacts bucket as it already exists.
[2025-01-06 17:17:05] INFO - Updating the component recipe com.example.windowstest01-1.0.0.
[2025-01-06 17:17:05] INFO - Validating the file size of the built recipe /Users/hogehoge/temp/windows-test-20250106/greengrass-build/recipes/com.example.windowstest01-1.0.0.yaml
[2025-01-06 17:17:05] INFO - Validating the built recipe against the Greengrass recipe schema.
[2025-01-06 17:17:05] INFO - Creating a new greengrass component com.example.windowstest01-1.0.0.
[2025-01-06 17:17:05] INFO - Created private version '1.0.0' of the component 'com.example.windowstest01' in the account.
AWS 側のコンソールにもコンポーネントが表示されました。
コンポーネントのデプロイ
コンポーネントの作成ができたらデプロイするだけです。作成したコンポーネントの画面を開いてデプロイしていきましょう。
このあとは下記の記事で紹介している内容と同じ作業になるので、詳細は割愛させていただきます。
(記事後半の「コンポーネントのデプロイ」という章になります)
動作確認
正常にデプロイできたら、Windows デバイス上で AWS IoT Greengrass のワークフォルダ(C:\greengrass\v2\work\com.example.windowstest01
)に移動して、hardware.txt
ができていることを確認しましょう。
最後に
これまで Greengrass を使う場合は Linux デバイスばかり使っていたので、Winsows 固有の仕様に合わせて Greengrass を使うのは少し工夫が必要だと思いました。
これを機会に Windows デバイスでの Greengrass の使い方をもう少し深堀りしていきたいと思います。
以上です。